#!/usr/bin/perl -w
# XFIG2PSAT converts XFIG 3.2 files into PSAT GIS files
#
# XFIG2PSAT <OPTIONS> FILEINPUT <FILEOUTPUT>
#
# Author:  Federico Milano
# Date:    19-Jun-2008
# Version: 1.0.0
#
#E-mail:    Federico.Milano@uclm.es
#Web-site:  http://www.uclm.es/area/gsee/Web/Federico

use strict;

# -----------------------------------------------------------------------
# variable declaration
# -----------------------------------------------------------------------

my $nargin = 0;
my $verbose = 0;
my $helpmsg = 0;
my $type = 0;
my $new = 0;
my $points;
my $npoly = 0;
my ($i,$h,$k,$j,$n);
my (@dum,@xdata,@ydata);

# -----------------------------------------------------------------------
# check inputs
# -----------------------------------------------------------------------
$nargin = @ARGV;
$nargin || die "Error: No input data file.\n";
my $title1 = 'Generic XFIG 3.2 Format File '.$ARGV[0];

# -----------------------------------------------------------------------
# check options
# -----------------------------------------------------------------------

while ($ARGV[0] =~ /^-/) {
    if ($ARGV[0] =~ /v/) {$verbose = 1;}
    if ($ARGV[0] =~ /h/) {$helpmsg = 1;}
    shift(@ARGV);
    $nargin--;
    if ($nargin == 0) { 
	last;
    }
} 

# -----------------------------------------------------------------------
# help (if requested)
# -----------------------------------------------------------------------
if ($helpmsg) {
    print "\nXFIG2PSAT converts XFIG 3.2 files into PSAT GIS files.\n\n";
    print "xfig2psat <options> fileinput <fileoutput>\n";
    print "  -v   verbose\n";
    print "  -h   print this help and exit\n\n";
    print "Author:   Federico Milano\n";
    print "Date:     19-Jun-2008\n";
    print "Version:  1.0.0\n\n";
    print "E-mail:   Federico.Milano\@uclm.es\n";
    print "Web-site: www.uclm.es/are/gsee/Web/Federico\n";
    die "\n";
}

# -----------------------------------------------------------------------
# define output file name (if necessary)
# -----------------------------------------------------------------------
if ($nargin == 1) {
    $ARGV[1] = $ARGV[0];
    $ARGV[1] =~ s/^d*_*/d_/;
    $ARGV[1] =~ s/[^\w\.]/_/g;
    $ARGV[1] =~ s/\..+$/.m/;
} elsif ($nargin == 0) {
    die "Error: Input file name is missing.\n";
}

# -----------------------------------------------------------------------
# open input data file
# -----------------------------------------------------------------------
print "Opening XFIG file \"$ARGV[0]\"...\n";
open(IN,$ARGV[0]) || die "cannot open $ARGV[0]: $!\n";

# -----------------------------------------------------------------------
# open output data file
# -----------------------------------------------------------------------
print "Writing PSAT file \"$ARGV[1]\"...\n";
open(OUT,">$ARGV[1]") || die "cannot open $ARGV[1]: $!\n";

# -----------------------------------------------------------------------
# write output data file
# -----------------------------------------------------------------------
print OUT "% File generated by PSAT.\n";
print OUT "% "."-" x 78 . "\n";
print OUT "% Author:   Federico Milano\n";
print OUT "% E-mail:   Federico.Milano\@uclm.es\n";
print OUT "% Web-site: www.uclm.es/are/gsee/Web/Federico\n";
print OUT "% "."-" x 78 . "\n";
print OUT "% $title1\n";

# -----------------------------------------------------------------------
# scan input data file
# -----------------------------------------------------------------------
$_ = <IN>; # dummy line
chomp;
if (!/^#FIG 3\.2/) {
    die "The file is not written in the XFIG 3.2 format.\n";
}

my $orientation = <IN>;
chomp $orientation;
$verbose && print "Orientation = $orientation\n";

my $justification = <IN>;
chomp $justification;
$verbose && print "Justification = $justification\n";

my $units = <IN>;
chomp $units;
$verbose && print "Units = $units\n";

my $papersize = <IN>;
chomp $papersize;
$verbose && print "Paper Size = $papersize\n";

my $magnification = <IN>;
chomp $magnification;
$verbose && print "Magnification = $magnification%\n";

my $multiplepage = <IN>;
chomp $multiplepage;
$verbose && print "Multiple Page = $multiplepage\n";

my $color = <IN>;
chomp $color;
$verbose && print "Color or Transparency = $color\n";

my $title2 = <IN>;
chomp $title2;
$title2 =~ s/^\#\s*//;
print OUT "% $title2\n\n";
print OUT "% "."-" x 78 . "\n\n";

$_ = <IN>;
chomp;
@dum = split(/\s+/);
my $resolution = $dum[0];
$n = 10;

while (<IN>) {
    chomp;
    $n++;
    @dum = split(/\s+/);
    if (/^\#/) { # comment 
	next;
    } elsif (/^0 /) { # color (pseudo-object)
	$verbose && print "Line $n is a color\n";
	$type = 0;
	next;
    } elsif (/^1 /) { # ellipse
	$verbose && print "Line $n is an ellipse\n";
	$type = 1;
	next;
    } elsif (/^2 /) { # polyline
	$verbose && print "Line $n is a polyline\n";
	$type = 2;
	$points = $dum[15];
	$npoly++;
	next;
    } elsif (/^3 /) { # spline
	$verbose && print "Line $n is a spline\n";
	$type = 3;
	next;
    } elsif (/^4 /) { # text
	$verbose && print "Line $n is a text\n";
	$type = 4;
	next;
    } elsif (/^5 /) { # arc
	$verbose && print "Line $n is a arc\n";
	$type = 5;
	next;
    } elsif (/^6 /) { # compound object
	$verbose && print "Line $n is a compound object\n";
	$type = 6;
	next;
    } elsif (/^\s+/) { # data line
	if ($type == 2) {
	    $i = 0;
	    @xdata = ();
	    @ydata = ();
	    while (1) {
		$k = $i;
		shift @dum;
		foreach $j (@dum) {
		    $k++;
		    if (($k % 2) == 0) { $ydata[$k/2] = $j; } 
		    if (($k % 2) == 1) { $xdata[($k-1)/2] = $j; } 
		}
		$i += @dum;
		#print $i . "   " . 2*$points . "\n";
		last if $i >= 2*$points;
		$n++;
		$_ = <IN>;
		chomp;
		last unless $_;
		@dum = split(/\s+/);
	    }
	    shift @ydata;
	    printf OUT "\nGIS.x{$npoly} = [ ...     \n    ";
	    for ($j = 0; $j < @xdata; $j++) {
		printf OUT "$xdata[$j]; ";
		$h = ($j+1) % 6;
		next if !$j;
		if ($h == 0) { printf OUT "\n    "; } 
	    }
	    if ($h != 0) { printf OUT "    "; }
	    printf OUT "]; \n";
	    printf OUT "\nGIS.y{$npoly} = [ ...     \n    ";
	    for ($j = 0; $j < @ydata; $j++) {
		printf OUT "$ydata[$j]; ";
		$h = ($j+1) % 6;
		next if !$j;
		if ($h == 0) { printf OUT "\n    "; } 
	    }
	    if ($h != 0) { printf OUT "    "; }
	    printf OUT "]; \n";
	}
    } else {
	$verbose && print "Warning: Line $n does not seem " .
	    "properly formed and will be ignored.\n";
	$type = -1;
    }
}

# -----------------------------------------------------------------------
# close input and output files
# -----------------------------------------------------------------------
close(IN) || die "cannot close $ARGV[0]: $!\n";
close(OUT) || die "cannot close $ARGV[1]: $!\n";
print "Conversion completed.\n";

# -----------------------------------------------------------------------
# write Bus.con
# -----------------------------------------------------------------------
#$format = "%4d 1 %8.5f %8.5f 1 1";
#$nbus >= 0 && print OUT "Bus.con = [ ...\n";
#for ($i = 1; $i <= $nbus-1; $i++) {
#    printf OUT "$format;\n",$i,$ein[$i] || 1,$ang[$i] || 0;
#}
#$i = $nbus;
#$nbus >= 0 && printf OUT "$format];\n\n",$i,$ein[$i] || 1,$ang[$i] || 0;
